﻿using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using ToolMonitoring.WebApi.Core;

namespace ToolMonitoring.WebApi.Filters
{
	public class GlobalExceptionFilter : IExceptionFilter
	{
		private readonly ILogger<GlobalExceptionFilter> _logger;
		public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger)
		{
			_logger = logger;
		}

		public void OnException(ExceptionContext context)
		{
			//异常返回结果包装
			var rspResult = ApiResult<object>.ErrorResult(context.Exception.Message);
			//日志记录
			_logger.LogError(context.Exception, context.Exception.Message);
			context.ExceptionHandled = true;
			context.Result = new InternalServerErrorObjectResult(rspResult);
		}

		public class InternalServerErrorObjectResult : ObjectResult
		{
			public InternalServerErrorObjectResult(object value) : base(value)
			{
				StatusCode = StatusCodes.Status500InternalServerError;
			}
		}
	}

	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	public class NoWrapperAttribute : Attribute
	{
	}

	public class ResultWrapperFilter:ActionFilterAttribute
	{
		public override void OnResultExecuting(ResultExecutingContext context)
		{
			var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
			var actionWrapper = controllerActionDescriptor?.MethodInfo.GetCustomAttributes(typeof(NoWrapperAttribute), false).FirstOrDefault();
			var controllerWrapper = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttributes(typeof(NoWrapperAttribute), false).FirstOrDefault();
			//如果包含NoWrapperAttribute则说明不需要对返回结果进行包装，直接返回原始值
			if (actionWrapper != null || controllerWrapper != null)
			{
				return;
			}

			//根据实际需求进行具体实现
			var rspResult = new ApiResult<object>();
			if (context.Result is ObjectResult)
			{
				var objectResult = context.Result as ObjectResult;
				if (objectResult?.Value == null)
				{
					// rspResult.Message = "未找到资源";
					context.Result = new ObjectResult(rspResult);
				}
				else
				{
					//如果返回结果已经是ResponseResult<T>类型的则不需要进行再次包装了
					if (objectResult.DeclaredType.IsGenericType && objectResult.DeclaredType?.GetGenericTypeDefinition() == typeof(ApiResult<>))
					{
						return;
					}
					rspResult.Data = objectResult.Value;
					context.Result = new ObjectResult(rspResult);
				}
				return;
			}
		}
	}
}
